home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / mas.lha / MAS / mas.c < prev    next >
C/C++ Source or Header  |  1995-07-30  |  15KB  |  450 lines

  1. /* mas.c */
  2.  
  3. #include "exec/io.h"
  4. #include "exec/libraries.h"
  5. #include "dos/dos.h"
  6. #include "dos/rdargs.h"
  7. #include "rexx/rexxio.h"
  8. #include "rexx/rxslib.h"
  9. #include "sh/sub.h"
  10. #include "techprg.h"
  11.  
  12. #include "proto/exec_protos.h"
  13. #include "proto/dos_protos.h"
  14. #include "proto/rexxsyslib_protos.h"
  15.  
  16. typedef unsigned short int uword;
  17. typedef unsigned long int ulong;
  18.  
  19. _main(void);
  20. ulong RexxCmd(ubyte *),GetSIG(void),doarea(struct AreaCfg *,ulong),
  21.     input(u_char *);
  22. long NumRexxFnc(u_char *),strval(u_char *);
  23. u_char *RexxFnc(u_char *),*fprint(u_char *,UWORD);
  24. void MakeTable(u_char **,u_char *,u_char *),GetAccess(void),
  25.     dotext(struct SigDat *sigp),
  26.     *SendBBSMsg(uword,void *),ScanAreas(struct SigDat *),gethotkey(void);
  27.  
  28. struct Library *RexxSysBase;
  29. struct MinList *sigs;
  30. struct SigDat *sig;
  31. struct MsgPort *ReplyPort,*TCP;
  32. struct BBSMsg bbsmsg;
  33. struct RdArgs *ra;
  34.  
  35. ulong args[5],user,inter,totals[32],news[32],areanews,node,total,new,strv;
  36. u_char cmd[32],APortName[32],Command[256],ibuf[32],buf[64],fprbuf[128],
  37.     fncbuf[128],access[64],*FncArgs[16],FncSpace[128],
  38.     template[]="SIG/N,ALL/S,NEW/S,FORCE/S,CONT/S,USER/K/N",
  39.     v[]="$VER: Message Area Scanner 1.50";
  40.  
  41. #define ARG_ALL     args[1]
  42. #define ARG_NEW     args[2]
  43. #define ARG_FORCE   args[3]
  44. #define ARG_CONT    args[4]
  45.  
  46. _main(void) {
  47. struct SigDat *tmp;
  48. struct Node *misc;
  49. uword i,o,toscan,numsigs;
  50. u_char *t;
  51.     GetProgramName(cmd,32);
  52.     if(!(ra=ReadArgs(template,args,NULL))) {
  53.         PrintFault(i=IoErr(),cmd);
  54.         return(i);
  55.     } else {
  56.         i=RETURN_FAIL;
  57.         if(RexxSysBase=OpenLibrary("rexxsyslib.library",LIBRARY_MINIMUM)) {
  58.             if(ReplyPort=CreateMsgPort()) {
  59.                 SendBBSMsg(ID_INCOPENCOUNT,NULL);
  60.                 if(TCP) {
  61.                     sigs=SendBBSMsg(ID_GETSIGS,NULL);
  62.                     if(args[5]) {
  63.                         node=*(ulong *)args[5];
  64.                         sprint(APortName,"Tech_%ld",node);
  65.                         user=1;
  66.                     }
  67.                     GetAccess();
  68.                     toscan=0;
  69.                     if(!ARG_ALL) toscan=args[0]?*((ULONG *)args[0]):GetSIG();
  70.                     while(TRUE) {
  71.                         total=0;
  72.                         new=0;
  73.                         if(toscan!=-1) {
  74.                             numsigs=0;
  75.                             tmp=sigs->mlh_Head;
  76.                             while(tmp->Node.mln_Succ) {
  77.                                 if(numsigs+1==toscan) sig=tmp;
  78.                                 tmp=tmp->Node.mln_Succ;
  79.                                 numsigs++;
  80.                             }
  81.                             if(toscan<=numsigs) {
  82.                                 i=RETURN_OK;
  83.                                 if(toscan) ScanAreas(sig);
  84.                                     else if(ARG_CONT) {
  85.                                     sig=sigs->mlh_Head;
  86.                                     sig->Node.mln_Succ;
  87.                                     dotext(sig);
  88.                                     for(o=1;o<=numsigs;o++) {
  89.                                         if(access[o]) {
  90.                                             ScanAreas(sig);
  91.                                             total+=*totals;
  92.                                             totals[o-1]=*totals;
  93.                                             if(user) {
  94.                                                 new+=areanews;
  95.                                                 news[o-1]=areanews;
  96.                                             }
  97.                                         }
  98.                                         sig=sig->Node.mln_Succ;
  99.                                     }
  100.                                     if(user) print("\nTotal new messages: %ld\n",new);
  101.                                         else rawprint("\n");
  102.                                 } else {
  103.                                     sig=sigs->mlh_Head;
  104.                                     sig->Node.mln_Succ;
  105.                                     for(o=1;o<=numsigs;o++) {
  106.                                         if(access[o]) {
  107.                                             ScanAreas(sig);
  108.                                             total+=*totals;
  109.                                             totals[o-1]=*totals;
  110.                                             if(user) {
  111.                                                 new+=areanews;
  112.                                                 news[o-1]=areanews;
  113.                                                 print("\nTotal for all areas so far: %ld messages, %ld new.\n",total,new);
  114.                                             } else print("\nTotal for all SIGs so far: %ld messages.\n",total);
  115.                                             gethotkey();
  116.                                         }
  117.                                         sig=sig->Node.mln_Succ;
  118.                                     }
  119.                                     RexxCmd("LogEntry Examining message area summary");
  120.                                     rawprint("\fMessage Area Scanner by Sami Klemola.\n\n");
  121.                                     fprint("Nr  SIG",36);
  122.                                     print("Total%s",user?"      New\n\n":"\n\n");
  123.                                     sig=sigs->mlh_Head;
  124.                                     for(o=1;o<=numsigs;o++) {
  125.                                         if(access[o]) {
  126.                                             sprint(buf,"%ld",o);
  127.                                             fprint(buf,4);
  128.                                             fprint(sig->Name,28);
  129.                                             print("%9ld",totals[o-1]);
  130.                                             if(user) print("%9ld\n",news[o-1]);
  131.                                                 else rawprint("\n");
  132.                                         }
  133.                                         sig=sig->Node.mln_Succ;
  134.                                     }
  135.                                     fprint("\nTotal",33);
  136.                                     print("%9ld",total);
  137.                                     if(user) print("%9ld\n",new);
  138.                                         else rawprint("\n");
  139.                                 }
  140.                             } else print("%s: illegal SIG number\n",cmd);
  141.                         } else {
  142.                             i=RETURN_OK;
  143.                             inter=FALSE;
  144.                         }
  145.                         if(!i&&inter) {
  146.                             i=RETURN_FAIL;
  147.                             gethotkey();
  148.                             toscan=GetSIG();
  149.                         } else break;
  150.                     }
  151.                     SendBBSMsg(ID_DECOPENCOUNT,NULL);
  152.                 } else print("%s: TechCon not running\n",cmd);
  153.                 DeleteMsgPort(ReplyPort);
  154.             } else print("%s: unable to create a message port\n",cmd);
  155.         } else print("%s: unable to open rexxsyslib.library\n",cmd);
  156.     }
  157.     FreeArgs(ra);
  158.     return(i);
  159. }
  160.  
  161. void ScanAreas(struct SigDat *toscan) {
  162. struct Node *areanode;
  163. struct AreaCfg *area;
  164. ulong areatotal,areanew;
  165. u_char *t;
  166.     areanode=&toscan->Areas;
  167.     areanode=areanode->ln_Succ;
  168.     area=(struct AreaCfg *)areanode->ln_Name;
  169.     sprint(buf,"HasMsgAcc %ld %ld",node,area->AreaNr);
  170.     if(user) if(!(NumRexxFnc(buf))) {
  171.         if(!ARG_CONT) rawprint("\nYou do not have access to this SIG.\n");
  172.         return();
  173.     }
  174.     if(!ARG_CONT) dotext(toscan);
  175.     *totals=0;
  176.     areanews=0;
  177.     while(areanode->ln_Succ) {
  178.         areatotal=area->HiMsg?area->HiMsg-area->LowMsg+1:0;
  179.         if(user) {
  180.             sprint(buf,"GetHighRead %ld %ld",node,area->AreaNr);
  181.             areanew=areatotal?area->HiMsg-NumRexxFnc(buf):0;
  182.         }
  183.         if(area->Type&1) if(doarea(area,areanew)) {
  184.             *totals+=areatotal;
  185.             areanews+=areanew;
  186.             sprint(buf,"%ld",area->AreaNr);
  187.             fprint(buf,4);
  188.             fprint(area->Name,28);
  189.             print("%9ld%9ld%9ld",area->LowMsg,area->HiMsg,areatotal);
  190.             if(user) print("%9ld\n",areanew);
  191.                 else rawprint("\n");
  192.         }
  193.         areanode=areanode->ln_Succ;
  194.         area=(struct AreaCfg *)areanode->ln_Name;
  195.     }
  196.     if(!ARG_CONT) if(user)
  197.         print("\nTotal: %ld messages, %ld new.\n",*totals,areanews);
  198.         else print("\nTotal: %ld messages.\n",*totals);
  199. };
  200.  
  201. ulong doarea(struct AreaCfg *area,ulong areanew) {
  202.     if(!user) return(TRUE);
  203.     if(ARG_NEW&&!areanew) return(FALSE);
  204.     sprint(buf,"HasMsgAcc %ld %ld",node,area->AreaNr);
  205.     if(NumRexxFnc(buf)) {
  206.         if(ARG_FORCE) return(TRUE);
  207.         sprint(buf,"GetAreaMode %ld %ld",node,area->AreaNr);
  208.         return(NumRexxFnc(buf));
  209.     }
  210.     return(FALSE);
  211. };
  212.  
  213. void dotext(struct SigDat *sigp) {
  214.     sprint(buf,"LogEntry Scanning%s%s areas of %s...",
  215.         ARG_NEW?" for new messages in ":" ",ARG_FORCE|!user?"all":"joined",
  216.         ARG_CONT?(u_char *)".":(u_char *)sigp->Name);
  217.     if(ARG_CONT) strcpy(&buf[strlen(buf)-8],"...");
  218.     print("\fMessage Area Scanner by Sami Klemola.\n\n%s\n\n",&buf[9]);
  219.     buf[strlen(buf)-3]=0;
  220.     if(user) RexxCmd(buf);
  221.     fprint("Nr  Name",38);
  222.     print("Low     High    Total%s",user?"      New\n\n":"\n\n");
  223. };
  224.  
  225. void GetAccess(void) {
  226. struct Node *areanode;
  227. struct AreaCfg *area;
  228. uword i;
  229.     sig=sigs->mlh_Head;
  230.     i=1;
  231.     while(sig->Node.mln_Succ) {
  232.         areanode=&sig->Areas;
  233.         areanode=areanode->ln_Succ;
  234.         area=(struct AreaCfg *)areanode->ln_Name;
  235.         sprint(buf,"HasMsgAcc %ld %ld",node,area->AreaNr);
  236.         access[i]=user?(NumRexxFnc(buf)?TRUE:FALSE):TRUE;
  237.         sig=sig->Node.mln_Succ;
  238.         i++;
  239.     }
  240. };
  241.  
  242. ulong GetSIG(void) {
  243. uword i,o;
  244.     rawprint("\fSIGs available:\n\n");
  245.     sig=sigs->mlh_Head;
  246.     i=1;
  247.     while(sig->Node.mln_Succ) {
  248.         if(access[i]) {
  249.             sprint(buf,"%ld",i);
  250.             fprint(buf,4);
  251.             print("%s\n",sig->Name);
  252.         }
  253.         sig=sig->Node.mln_Succ;
  254.         i++;
  255.     }
  256.     while(TRUE) {
  257.         if(!(input("\nSelect one to scan (enter to exit, 0 for all): ")))
  258.             return(-1);
  259.         if((o=strval(ibuf))<i) if(!o||access[o]) break;
  260.             else rawprint("\nYou do not have access to this SIG.\n");
  261.     }
  262.     inter=TRUE;
  263.     return(o);
  264. }
  265.  
  266. u_char *fprint(u_char *str,UWORD len) {
  267. UWORD i;
  268.     strcpy(fprbuf,str);
  269.     for(i=strlen(fprbuf);i<len;i++) fprbuf[i]=32;
  270.     fprbuf[i]=0;
  271.     rawprint(fprbuf);
  272. };
  273.  
  274. long strval(u_char *str) {
  275.     if(StrToLong(str,&strv)<0) return(-1);
  276.     return(strv);
  277. };
  278.  
  279. void gethotkey(void) {
  280.     rawprint("\nPress enter... ");
  281.     while(FGetC(Input())!=10);
  282.     rawprint("\n");
  283. };
  284.  
  285. ulong input(u_char *query) {
  286. ulong i,c;
  287. u_char *t;
  288.     rawprint(query);
  289.     t=ibuf;
  290.     i=0;
  291.     while(i<30) if((c=FGetC(Input()))==10) break; else {
  292.         *t++=c;
  293.         i++;
  294.     }
  295.     *t=0;
  296.     return(i);
  297. };
  298.  
  299. /* This function creates the argument array used by RexxFnc(). You must
  300.    provide the data areas for it. See the code for RexxFnc() for more. */
  301.  
  302. void MakeTable(u_char **table,u_char *tabledata,u_char *string) {
  303. u_char *t,*s;
  304. uword i;
  305.     clear(table,128);
  306.     clear(t=tabledata,128);
  307.     s=string;
  308.     for(i=0;i<16;i++) {
  309.         table[i]=t;
  310.         while(*s&&(*s!=32)) *t++=*s++;
  311.         if(!*s) break;
  312.         while(*s==32) s++;
  313.         t++;
  314.     }
  315. }
  316.  
  317. /*
  318.  * RexxCmd - Send a command to an ARexx port
  319.  *
  320.  * You should have rexxsyslib.library open and a global variable called
  321.  * APortName containing the name of the ARexx port the command should be
  322.  * sent to.  You also need a message port called ReplyPort.
  323.  *
  324.  * Usage: RexxCmd("<Command>");
  325.  *
  326.  * Return: 0 - success, 1 - no port, 2 - error
  327.  *
  328.  */
  329.  
  330. ulong RexxCmd(ubyte *arg) {
  331. struct RexxMsg *rxm;
  332. struct MsgPort *RxPort;
  333. ulong res;
  334.     res=0;
  335.     if(rxm = CreateRexxMsg(ReplyPort, NULL, NULL)) {
  336.         rxm->rm_Node.mn_Node.ln_Name = "REXX";
  337.         rxm->rm_Action = RXCOMM;
  338.         ARG0(rxm) = CreateArgstring(arg, strlen(arg));
  339.         Forbid();
  340.         if(RxPort = FindPort(APortName)) PutMsg(RxPort, (struct Message *)rxm);
  341.         Permit();
  342.         if(!RxPort) {
  343.             res=1;
  344.         } else {
  345.             WaitPort(ReplyPort);
  346.             while(GetMsg(ReplyPort)) ;
  347.             if(rxm->rm_Result1 > 4) {
  348.                 res=2;
  349.             }
  350.         }
  351.         ClearRexxMsg(rxm, 1);
  352.         DeleteRexxMsg(rxm);
  353.     }
  354.     return(res);
  355. }
  356.  
  357. /* NumRexxFnc - Call a numeric ARexx function (Written by S.Klemola)
  358.  
  359. /* Calls an ARexx function that returns a numeric value. Returns FALSE
  360.    by default. You get this if an error occurs. Usage like RexxFnc(). */
  361.  
  362. long NumRexxFnc(u_char *Fnc) {
  363. long v;
  364. u_char *t;
  365.     v=0;
  366.     if(t=RexxFnc(Fnc)) v=strval(t);
  367.     return(v);
  368. };
  369.  
  370. /*
  371.  * RexxFnc - Call an ARexx function (Revised by S.Klemola)
  372.  *
  373.  * Requires the same stuff as RexxCmd
  374.  *
  375.  * Note! Instead of duplicating the string returned by the function, it
  376.  * is copied to a global buffer, fncbuf. You must provide this. Do *NOT*
  377.  * call free() on the result! Note also the new usage. Returns NULL if an
  378.  * error occurred.
  379.  *
  380.  * Usage: result = RexxFnc("<Function> [<Arg1>] [<Arg2] [...]",);
  381.  *
  382.  */
  383.  
  384. u_char *RexxFnc(u_char *Fnc) {
  385. struct RexxMsg *rxm;
  386. struct MsgPort *RxPort;
  387. int cc;
  388. ubyte *res;
  389.     MakeTable(FncArgs,FncSpace,Fnc);
  390.     res = fncbuf;
  391.     if(rxm = CreateRexxMsg(ReplyPort, NULL, NULL)) {
  392.         rxm->rm_Node.mn_Node.ln_Name = "REXX";
  393.         rxm->rm_Action = RXFUNC | RXFF_RESULT;
  394.         for(cc = 0; FncArgs[cc] && cc < 16; cc++) rxm->rm_Args[cc] =
  395.             CreateArgstring(FncArgs[cc], strlen(FncArgs[cc]));
  396.         rxm->rm_Action |= (cc - 1) & 0xf;
  397.         Forbid();
  398.         if(RxPort = FindPort(APortName)) PutMsg(RxPort, (struct Message *)rxm);
  399.         Permit();
  400.         if(!RxPort) {
  401.             res = 0;
  402.         } else {
  403.             WaitPort(ReplyPort);
  404.             while(GetMsg(ReplyPort)) ;
  405.             if(!rxm->rm_Result1) {
  406.                 if(rxm->rm_Result2) {
  407.                     strcpy(res,(u_char *)rxm->rm_Result2);
  408.                     DeleteArgstring((ubyte *)rxm->rm_Result2);
  409.                 }
  410.             } else if(rxm->rm_Result1 > 5) res = 0;
  411.         }
  412.         ClearRexxMsg(rxm, 1);
  413.         DeleteRexxMsg(rxm);
  414.     }
  415.     return(res);
  416. }
  417.  
  418. /* Enhanced by S. Klemola */
  419.  
  420. /*
  421.  * Note-a-mundos:
  422.  *
  423.  * - Provide a global uninitialized BBSMsg structure
  424.  * - Provide a global variable called TCP (it can be used to check after
  425.  *   a call to this function if TechCon is running)
  426.  * - clear() is an assembly function that performs the same as bzero()
  427.  * - Permit() has only significance when the port wasn't found. Otherwise
  428.  *   the Wait() call will already have braken Forbid()
  429.  *
  430.  */
  431.  
  432. void *SendBBSMsg(uword ID,void *data) {
  433. struct BBSMsg *sndmsg;
  434.     sndmsg=&bbsmsg;
  435.     clear(sndmsg,sizeof(struct BBSMsg));
  436.     sndmsg->SendingNode = -1;
  437.     sndmsg->ID = ID;
  438.     sndmsg->data = data;
  439.     sndmsg->Msg.mn_ReplyPort = ReplyPort;
  440.     Forbid();
  441.     if(TCP=FindPort("TechCon_Private")) {
  442.         PutMsg(TCP,(struct Message *)sndmsg);
  443.         Wait(1 << ReplyPort->mp_SigBit);
  444.         while(GetMsg(ReplyPort));
  445.     }
  446.     Permit();
  447.     return(TCP?sndmsg->result:NULL);
  448. }
  449.  
  450.